package com.dymall.common.domain;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dymall.common.utils.BeanUtils;
import com.dymall.common.utils.CollUtils;
import com.dymall.common.utils.Convert;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageDTO<T> {
    protected Long total;//总记录数
    protected Long pages;//总页数
    protected List<T> list;//当前页的数据列表

    public static <T> PageDTO<T> empty(Long total, Long pages) {
        //创建一个空的分页对象，包含总记录数和总页数，但数据列表为空
        return new PageDTO<>(total, pages, CollUtils.emptyList());
    }
    public static <T> PageDTO<T> empty(Page<?> page) {
        //根据传入的 Page<?> 对象创建一个空的分页对象,保留分页信息（总记录数和总页数），但数据列表为空。
        return new PageDTO<>(page.getTotal(), page.getPages(), CollUtils.emptyList());
    }

    public static <T> PageDTO<T> of(Page<T> page) {
        //将一个 Page<T> 对象转换为 PageDTO<T> 对象
        //如果 Page<T> 为空或其记录为空，则返回一个空的分页对象；否则返回包含分页信息和数据列表的分页对象

        //使用场景：在分页查询后，将底层分页对象（如 MyBatis Plus 的 Page<T>）转换为统一的分页响应对象。
        if(page == null){
            return new PageDTO<>();
        }
        if (CollUtils.isEmpty(page.getRecords())) {
            return empty(page);
        }
        return new PageDTO<>(page.getTotal(), page.getPages(), page.getRecords());
    }
    public static <T,R> PageDTO<T> of(Page<R> page, Function<R, T> mapper) {
        //将一个 Page<R> 对象中的记录通过映射函数 mapper 转换为另一种类型的记录 T，并返回新的分页对象
        if(page == null){
            return new PageDTO<>();
        }
        if (CollUtils.isEmpty(page.getRecords())) {
            return empty(page);
        }
        return new PageDTO<>(page.getTotal(), page.getPages(),
                page.getRecords().stream().map(mapper).collect(Collectors.toList()));
    }
    public static <T> PageDTO<T> of(Page<?> page, List<T> list) {
        //根据传入的 Page<?> 对象和自定义的 List<T> 创建一个新的分页对象
        //分页信息来自 Page<?>，而数据列表由调用者提供
        return new PageDTO<>(page.getTotal(), page.getPages(), list);
    }

    public static <T, R> PageDTO<T> of(Page<R> page, Class<T> clazz) {
        //将 Page<R> 中的记录通过 BeanUtils.copyList 方法批量转换为指定类型的对象 T，并返回新的分页对象
        return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz));
    }

    public static <T, R> PageDTO<T> of(Page<R> page, Class<T> clazz, Convert<R, T> convert) {
        //将 Page<R> 中的记录通过自定义的转换器 Convert<R, T> 转换为指定类型的对象 T，并返回新的分页对象
        return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz, convert));
    }
}
